﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace CoolCode.Web.Mvc 
{ 
    /// <summary>
    /// Submit ActionFilter
    /// </summary> 
    [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
    public class SubmitFilter : ActionFilterAttribute, IActionFilter
    {
        public string OrderBy { get; set; }

        public int PageSize { get; set; }

        public string PageParam { get; set; }

        public string OrderByParam { get; set; }

        public SubmitFilter()
        {
            PageParam = "page"; 
            OrderByParam = "orderby";
        }

        private int pageIndex = 0;

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.Controller.ContainsKey(PageParam))
            {
                pageIndex = filterContext.Controller.ValueOf<int>(PageParam);
            }

            if (filterContext.Controller.ContainsKey(OrderByParam))
            {
                OrderBy = filterContext.Controller.ValueOf<string>(OrderByParam);
            }

            //if (filterContext.ActionParameters.ContainsKey(PageParam))
            //{
            //    int.TryParse(filterContext.ActionParameters[PageParam].ToString(), out pageIndex);
            //}

            //if (filterContext.ActionParameters.ContainsKey(OrderByParam))
            //{
            //    OrderBy = filterContext.ActionParameters[OrderByParam].ToString();
            //}

            //base.OnActionExecuting(filterContext);            
        }

        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            if (!(filterContext.Result is ViewResultBase))
            {
                throw new NotSupportedException("filterContext.Result must be ViewResultBase type!");
            }

            ViewResultBase result = (ViewResultBase)filterContext.Result;
            if (!(result.ViewData.Model is IQueryable))
            {
                throw new NotSupportedException("Model must be IQueryable type!");
            }

            Type elementType = result.ViewData.Model.GetType().GetGenericArguments()[0];

            if (string.IsNullOrEmpty(this.OrderBy))
            {
                this.OrderBy = GetDefaultSortedField(elementType);
            }

            IQueryable query = (IQueryable)result.ViewData.Model;

            if (string.IsNullOrEmpty(this.OrderBy))
            {
                query = query.OrderBy(this.OrderBy);
            }

            object newModel = Activator.CreateInstance(
                    typeof(PaginatedList<>).MakeGenericType(elementType),
                    new object[] { query, pageIndex, this.PageSize });

            result.ViewData.Model = newModel;
            //base.OnResultExecuting(filterContext);
        }

        private static string GetDefaultSortedField(Type modelType)
        {
            if (modelType.IsSubclassOf(typeof(IEntity)))
            {
                return "ID";
            }
            var ps = modelType.GetProperties().Where(p => p.PropertyType.IsSubclassOf(typeof(IEntity))).ToArray();
            if (ps.Length > 0)
            {
                PropertyInfo p = ps.First();
                return p.Name + "." + GetDefaultSortedField(p.PropertyType);
            }
            return string.Empty;
        }

        //private static string getDefaultSortedFieldHelper(Type modelType)
        //{
        //}

    }
}
